.so .bitmacros
.TH \*(BS 1 "April, 1998" "BitKeeper Inc."
.SH NAME
\*(BS \- introduction to the \*(BM version of \*S
.SH DESCRIPTION
\*(BS is a low level interface to revision control.  For a higher level
interface, please see the 
.BR bitkeeper (1)
man page.
.PP
The \*(BS source control system manages multiple revisions of files.
It is modeled after the \*(AT system, with features added from \*R, as
well as extensions found in neither predecessor.  \*(BS automates the
storing, retrieval, logging, identification, and merging of revisions.
\*(BS is useful for text that is revised frequently, for example
programs, documentation, \s-2HTML\s0 files, graphics, papers, and form
letters.
.PP
The basic user interface is extremely simple, and is identical to that
of \*R (\*S commands are supported as well).  Only two commands are
needed:
.BR ci (1)
and
.BR co (1).
.BR ci ,
short for \*(lqcheck in\*(rq, deposits the contents of a file into an
archival file called an \*S file, or \*(lqs. file\*(rq.  An
\*S file contains all revisions of a particular file.
.BR co ,
short for \*(lqcheck out\*(rq, retrieves revisions from an \*S file.
.SS "Functions of \*(BS"
.IP \(rh 4
Store and retrieve multiple revisions of text.  \*(BS saves all old
revisions in a space efficient way.
Changes no longer destroy the original, because the
previous revisions remain accessible.  Revisions can be retrieved according to
ranges of revision numbers, symbolic names, dates, authors, and
states.
.IP \(rh
Maintain a complete history of changes.
\*(BS logs all changes automatically.
Besides the text of each revision, 
\*(BS stores the author,
the date and time (including timezone) of check-in,
the pathname of the file,
the hostname (and domain name) on which the change was made,
and a log message summarizing the change.
The logging makes it easy to find out
what happened to a module, without having to compare
source listings or having to track down colleagues.
.IP \(rh
Maintain a tree of revisions.  \*(BS can maintain separate lines of development
for each module.  It stores a tree structure that represents the
ancestral relationships among revisions.  
Release 2 of \*(BS will have expanded support for this feature.
.IP \(rh
Merge revisions and resolve conflicts.
Two separate lines of development of a module can be coalesced by merging.
If the revisions to be merged affect the same sections of code,
\*(BS alerts the user about the overlapping changes.
The 
.BR smoosh (1)
command is useful for merging.
.IP \(rh
Control releases and configurations.
Revisions can be assigned symbolic names
and marked as released, stable, experimental, etc.
With these facilities, configurations of modules can be
described simply and directly.
.IP \(rh
Automatically identify each revision with name, revision number,
creation time, author, etc.
The identification is like a stamp that can be embedded at an appropriate place
in the text of a revision.
The identification makes it simple to determine which
revisions of which modules make up a given configuration.
With the addition of hostnames and pathnames, each revision is globally unique,
a useful feature for distributed source management.
.IP \(rh
Minimize disk space.  \*(BS needs little extra space for
the revisions (only the differences).  If intermediate revisions are
deleted, the corresponding deltas are compressed accordingly.
Release 2 of \*(BS will support 
.B gzip-ed
\*S files
for even less disk usage.
.SS "Comparison to \*R and \*S"
.IP \(rh 4
.B Features.
\*(BS is a superset of \*R and \*S.  \*(BS added the \*R
features not found in \*S.  Conversion of \*R files to \*(BS \*S
files loses no information (this includes tags and arbitrarily complex
revision histories).
.IP \(rh
.B Compatibility
\*(BS is 100% file format compatible with \*(AT.  New features
have been added as new flags; the old \*S programs quietly ignore, but
preserve, new flags.  \*(BS is not file format compatible with \*R,
but it is feature compatible.  Features such as symbolic tags, file state,
etc., have been added to \*(BS.  Re-implementations of the most commonly
used \*R commands are also provided.
.IP \(rh
.B Performance.
One frequently voiced
concern is that \*S is slower than \*R.  That was true in \*(AT but
is not true in \*(BS.  \*(BS can get any delta in constant time, most
recent deltas are extracted in the same time as \*R, and all other
deltas are extracted in less time than \*R.
However, both tools can
perform all operations in less time than it takes to read the file from disk,
making the performance differences somewhat meaningless.
It is true that \*R can get top of trunk without reading the entire file,
resulting in less disk traffic.
\*S reads the entire file because it checksums the entire file before
completing any operations.  The checksum is used to insure file integrity;
\*R has no similar facility.  
.SS "Getting Started with \*(BS"
Before trying these examples, you will need to reset your path.  This is
because both the \*(BS system and the \*R system have commands with 
the same name.  If you are running in Bourne compatible shell, such as
.BR bash ,
then do this
.DS
PATH=/usr/bitsccs:$PATH
hash -r
.DE
If you are using a C compatible shell, such as
.BR csh ,
then do this
.DS
set path = ( /usr/bitsccs $path )
rehash
.DE
Suppose you have a file
.B foo.c
that you wish to put under control of \*(BS.
Invoke the check-in command
.DS
ci -i foo.c
.DE
This command creates an \*S directory,
creates an \*S file 
.B \*S/s.foo.c
in the
.B \*S
directory,
stores
.B foo.c
into it as revision 1.1, and
deletes
.BR foo.c .
.PP
Files in the \*S directory are called \*S files or .
.I "s. files"
(pronounced ``S dot files'';
the others are called working files, or .
.I gfiles
for \*(lqgotten files.\*(rq
.LP
If
.B ci
complains with the message
.DS
foo.c not checked in, use -i flag.
.DE
then you forgot to tell the system that you wanted to create a new
\*S file; retry with the -\fBi\fP flag (i for initialize).
.LP
To get back the working file
.B foo.c
in the previous example, use the check-out
command
.DS
co  foo.c
.DE
This command extracts the latest revision from the \*S file
and writes
it into
.BR foo.c .
If you want to edit
.BR foo.c ,
you must lock it as you check it out with the command
.DS
co  \-l  foo.c
.DE
You can now edit
.BR foo.c .
If you had tried to edit 
.B foo.c
without locking it, your editor should have warned you that the file is
read only.
.PP
Locking assures that you, and only you, can check in the next update, and
avoids nasty problems if several people work on the same file.
Even if a revision is locked, it can still be checked out for
reading, compiling, etc.  All that locking
prevents is a
.I "check-in"
by anybody but the locker.
.PP
Suppose after some editing you want to know what changes that you have made.
The command
.DS
diffs  foo.c
.DE
tells you the difference between the most recently checked-in version
and the working file.
.LP
You can check the file back in by invoking
.DS
ci  foo.c
.DE
This increments the revision number properly.
If
.B ci
tells you
.DS
Clean foo.c (no diffs)
.DE
then you have tried to check in a file that you didn't modify.  If you
really wanted a revision with no changes (which is fine), then use the
\fB-f\fP flag (the force flag).
.LP
On the subject of cleaning, the 
.B clean
command can be used to clean all files which have been locked but not
edited.  Just say
.DS
clean
.DE
and it will warn about each file that has been modified, but remove the
file (and associated lock) for all unchanged files.
.LP
Note that 
.B clean
automatically came up with a list of files to clean, there was no
explicit list.  All commands in \*(BS have this feature, see the
section below on file name expansion for more details.
.LP
To view the revision history of a file, try
.DS
prs file
.DE
.LP
Suppose you have a software product that is ready for alpha testing.  You're
going to ship this product your customers, and you are going to continue
bug fixing, performance enhancements, etc.  In order to track problems, you
would like to remember which revisions of the files in the alpha.  You
can mark the files like so
.DS
admin -sAlpha:
.DE
That says put the tag 
.B Alpha
on the highest numbered revision of each file in the \*S directory.
Note that the highest 
.B existing
revision is used; you almost certainly want to run 
.B clean 
and/or
.B ci
before tagging the files.
.LP
Once you have tagged the files, you can use the tag just like a revision
number.  For example, to see what you've done since the alpha, you can
say
.DS
diffs -rAlpha
.DE
.LP
For the \*S fans out there, the standard \*S command interfaces
are also available.  To check in a file, you can use
.B ci
but you can also use
.BR delta .
These two commands do the same thing
.DS
ci foo.c
delta foo.c
.DE
For the most part, the two are just different command line interfaces to
the same idea.  There are some differences, consult the man pages for
more information.  In particular, users writing conversion scripts will
want to look closely at
.BR delta (1)
which has extensive support for such problems.
.LP
To check out a file using the \*S command, try
.DS
get foo.c		# same as co foo.c
get -e foo.c	# same as co -l foo.c
.DE
.LP
It may seem redundant to have both versions, but the \*R commands are
well known, quicker to type, etc.  The \*S commands are frequently
built into Makefile rules (and sometimes into the fingers of old time
Unix hackers).
.SS "Key word expansion"
\*(BS support both \*S style and \*R style keywords.  A keyword
is a well known string that is replaced, in an unlocked & checked out file,
with some information about the file.  Examples include the file name, the
date, the author of the revision, the revision number, etc.  
.LP
Suppose you wanted to have some information in the file like so:
.DS
/*
 * Version 1.5 of foo.c by lm@bitmover.com
 */
.DE
To do this, lock the file, edit it, and make the comment look like:
.DS
/*
 * Version %\I% of %\M% by %\@%
 */
.DE
.LP
Since \*R
is in widespread use, \*(BS supports \*R keywords.  However, to get
\*R keywords, the 
.B R
flag must be set in the \*S file.  You can use
.B admin
to set the flag; the conversion tool,
.BR rcs2sccs ,
sets this flag automatically.
.LP
A special sort of symbol is frequently added to source code for identification
in the field.  Typical usage is something like
.DS
static char *what = "%\W%";
.DE
which will expand to
.DS
static char *what = "@(#)foo.c	1.1";
.DE
in an unlocked file.
.LP
There is a command,
.BR what (1),
that looks through (binary) files for these strings and prints them.  This can
be useful to get revision information in the field.
.LP
To learn more about keywords, consult the
.BR get (1)
man page for \*S keywords, and the
.BR sccs-co (1)
man page for \*R keywords.
.SS "File name expansion"
All commands in \*(BS expand file names identically.  The complex expansion 
is the result of trying to support both the \*(AT command interface
and the more user friendly \*(BS command interface.  
\*(AT commands insisted that files
were specified as \f(CWs.foo\fP or \f(CWSCCS/s.foo\fP but never just
\f(CWfoo\fP.  \*(BS allows either specification, with \f(CWfoo\fP 
implying a corresponding \f(CWSCCS/s.foo\fP.  
.LP
In the following list of expansion methods, the first one that
works is the one that is used, so order is important.
.IP "\fIdir\fP" 10
If a directory is specified, and \fIdir/\*S\fP exists,
then the implied list is \fIdir/\*S/s.*\fP.
.IP ""
If a directory is specified, and \fIdir/\*S\fP does not exist,
then the implied list is \fIdir/s.*\fP.
.IP "\fI<Null>\fP" 
If no directory and no files are specified, and \fI./\*S\fP exists,
then the implied list is \fI\*S/s.*\fP.
.IP ""
If no directory and no files are specified, and \fI./\*S\fP does not exist,
then the implied list is \fIs.*\fP.
.IP "\fIs.file ...\fP
A list of \*S files is passed through unchanged.
.IP "\fIfile ...\fP
A list of regular files, which have corresponding \*S/s.files,
just converts the file names to s.files.
.LP
Note one major difference from \*(AT.  The original \*S 
.B get
command would place the g.file in the current working directory, regardless of
the path to the s.file.  For example,
.DS
$ get /foo/bar/blech/s.foo
.DE
would place the file in \f(CW./foo\fP, not \f(CW/foo/bar/foo\fP.
\*(BS does not follow this convention, the g.files are placed next
to the s.files, with one exception: if the s.file is in a \*S 
directory, the g.file is placed in the parent directory.  That one 
exception makes most old scripts work.  However, the -G option to 
.B get
can be used to force the name of the g.file to be anything you want.
.LP
Certain commands may choose to override the default file name expansion
mechanism.
One example is the
.BR clean (1)
command, when used with the 
.B -u 
option which unedits files, even those files with modifications.  This is
a safety mechanism which can be overridden by explicitly listing the files
rather than counting on automatic expansion of \fIs.*\fP o \fI\*S/s.*\fP, etc.
.SH ACKNOWLEDGEMENTS
Marc Rochkind, for writing the original \*S.
Walter Tichy, Paul Eggert, and all the other authors of \*R.  Symbolic tags,
the user interface, and even portions of this man page owe their existance
to \*R.
.SH AUTHOR
Larry McVoy, lm@bitmover.com.
.SH BUGS
.LP
Bug reports to support@bitkeeper.com.  Bug reports may be filed with
the bitbug(1) command.
.DE
.SH "SEE ALSO"
admin(1), sccs-ci(1), clean(1), sccs-co(1), delta(1), diffs(1), get(1), 
prs(1), rcs2sccs(1), sccssh(1), smoosh(1), and what(1).
